using System;
using System.Collections.Generic;
using Habanero.Base;
using Habanero.BO;
using Habanero.Faces.Base;
using FireStarterModeller.BO;

namespace FireStarterModeller.UI
{
    /// <summary>
    /// This inherits from LookupComboBoxMapper and is used to limit the list of classes available in the
    /// Lookup list to Classes that are not inherited from this.SubClass.
    /// </summary>
    public class SuperClassLookupComboBoxMapper : LookupComboBoxMapper
    {
        private DMClass _dmSubClass;

        public SuperClassLookupComboBoxMapper(IComboBox cbx, string propName, bool isReadOnly, IControlFactory factory)
            : base(cbx, propName, isReadOnly, factory)
        {
        }

        /// <summary>
        /// This is the sub class that the Super class is being selected for.
        /// </summary>
        public DMClass SubClass
        {
            get { return _dmSubClass; }
            set
            {
                if (_dmSubClass == value) return;
                _dmSubClass = value;
                SetupComboBoxItems();
            }
        }

        public override IBusinessObject BusinessObject
        {
            get { return base.BusinessObject; }
            set
            {
                if (value != null)
                {
                    SubClass = ((DMInheritanceRelationship) value).SubClass;
                }
                base.BusinessObject = value;
            }
        }

        public override void ApplyChangesToBusinessObject()
        {
            base.ApplyChangesToBusinessObject();
            //Brett: This is a hack to force the reverse relationship to load in the case where the 
            // Super Class is not yet persisted in the Database and the inheritanceRelationship.SubClasses will
            // therefore not load it.
            // In reality a better way of doing this is to use a Relationship Combo Box Mapper.
            DMInheritanceRelationship inheritanceRelationship = ((DMInheritanceRelationship)this.BusinessObject);
#pragma warning disable 168
            if (inheritanceRelationship == null) return; ;

            DMClass superClass = inheritanceRelationship.SuperClass;
#pragma warning restore 168
//            if (inheritanceRelationship.SuperClass == null || (inheritanceRelationship.SuperClass.ClassID != inheritanceRelationship.SuperClassID))
//            {
//                inheritanceRelationship.SuperClass =
//                                 BORegistry.DataAccessor.BusinessObjectLoader.GetBusinessObject<DMClass>("ClassID=" + inheritanceRelationship.SuperClassID);
//            }
        }

        /// <summary>
        /// Do customization of the Lookup list by overriding this method in an inheritor.
        /// </summary>
        /// <param name="col">The look up list retrieved from the businessobject that will be customised</param>
        protected override void CustomiseLookupList(Dictionary<string, string> col)
        {

            if (SubClass == null) return;
            BusinessObjectCollection<DMClass> subClasses = new BusinessObjectCollection<DMClass>();
            GetAllSubClasses(SubClass, subClasses);
            foreach (DMClass dmClass in subClasses)
            {
                RemoveBOFromList(col, dmClass);
            }
            RemoveBOFromList(col, SubClass);
        }

        private static void RemoveBOFromList(IDictionary<string, string> col, DMClass dmClass)
        {
            string foundKey = null;
            foreach (KeyValuePair<string, string> keyValuePair in col)
            {
                if (new Guid(keyValuePair.Value) != dmClass.ClassID.Value) continue;
                foundKey = keyValuePair.Key;
                break;
            }
            if (foundKey != null)
            {
                col.Remove(foundKey);
            }
        }

        private static void GetAllSubClasses(DMClass parentClass, BusinessObjectCollection<DMClass> businessObjectInfos)
        {
            BusinessObjectCollection<DMInheritanceRelationship> subClassInheritanceRelationships = parentClass.SubClassRelationships;

            foreach (DMInheritanceRelationship inheritanceRelationship in subClassInheritanceRelationships)
            {
                DMClass dmClass = inheritanceRelationship.SubClass;
                if (dmClass == null) continue;
                if (businessObjectInfos.Contains(dmClass)) continue;
                
                businessObjectInfos.Add(dmClass);
                GetAllSubClasses(dmClass, businessObjectInfos);
            }
        }
    }
}
